
#ifndef __LIBERTY_ENGINE_PERFCOUNTER_H__
#define __LIBERTY_ENGINE_PERFCOUNTER_H__

#if defined(WIN32) || defined(WIN64)

#include <windows.h>

#ifdef Yield
#undef Yield
#endif

#elif defined(__MACH__)

#include <stdint.h>
#include <sched.h>
#include <mach/mach_time.h>

#endif

namespace Liberty { namespace Engine {
    class Performance {
#if defined(WIN32) || defined(WIN64)
    public:
        typedef unsigned __int64 Counter;

    protected:
        static double  freqD;
        static Counter freq;

    public:
        static inline void query(Counter& v) {
            QueryPerformanceCounter((LARGE_INTEGER*)&v);
        }
        
        static inline void yield() {
            SwitchToThread();
        }

        static inline Counter fromSeconds(double d) {
            return ((Counter)((d) * freq));
        }

        static inline double toSeconds(Counter d) {
            return (((double)(d)) / freqD);
        }
#elif defined(__MACH__)
    public:
        typedef uint64_t Counter;
        
    protected:
        static mach_timebase_info_data_t freq;

    public:
        static inline void query(Counter& v) {
            v = mach_absolute_time();
        }

        static inline void yield() {
            sched_yield();
        }

        static inline double toSeconds(Counter d) {
            return (((double)(d)) * ((double)freq.numer) / ((double)freq.denom) / 1000000000.0);
        }

        static inline Counter fromSeconds(double s) {
            return (Counter)(s * ((double)freq.denom) * 1000000000.0 / ((double)freq.denom));
        }
#endif

    public:
        static void init();

    public:
        static Counter oneMillisecond;
    };
}}

#endif
